﻿using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Reflection;
using System.Windows.Forms;

namespace ShapeManager
{
    public class URectangleR : DrawObject
    {
        #region 字段|属性
        /// <summary> 旋转光标 </summary>
        protected Cursor RotateCursor { get; set; }
        /// <summary>  矩形角点 </summary>
        protected PointF[] Points { get; set; } = new PointF[4];
        public override int HandleCount => 9;   //手柄个数
        private int rotateHandleSize = 15;      //旋转手柄大小
        public override bool IsRotating { get => base.IsRotating; set => base.IsRotating = value; } 
        #endregion

        #region 构造函数
        public URectangleR() : this(0, 0, 1, 1) { }
        public URectangleR(int x, int y, int width, int height, int angle = 0) : base()
        {
            IsRotating = true;
            _rectangleF.X = x;
            _rectangleF.Y = y;
            _rectangleF.Width = width;
            _rectangleF.Height = height;
            Points = GetRotatedCorners(Region);
            Angle = angle;
            RotateCursor = new Cursor("Cursor/Rotate.cur");
            Description = "ROI";
            Type = ShapeType.RectangleR;
            Initialize();
        }
        public override void Normalize()
        {
            _rectangleF = URectangle.GetNormalizedRectangle(_rectangleF);
        }
        #endregion

        #region 基础方法
        public override DrawObject Clone()
        {
            URectangleR uRectangle = new URectangleR();
            uRectangle._rectangleF = this._rectangleF;
            uRectangle.ID = this.ID;
            uRectangle.Angle = this.Angle;
            Clone(uRectangle);
            return uRectangle;
        }
        public override void Draw(Graphics graphics)
        {
            //不感兴趣直接绘制
            if (!IsInterest)
            {
                //保留原来颜色
                Color tempBackColor = BackColor;
                BackColor = InterestColor;
                // 1.1、绘制（填充）背景区域
                //UseTransformDraw(DrawRegion, graphics);
                DrawRegion(graphics);
                // 1.2、绘制水平方向箭头
                UseTransformDraw(DrawVerticalDirectionArrows, graphics);
                // 1.3、绘制旋转手柄(圆弧)
                UseTransformDraw(DrawRotateHandle, graphics);
                // 2、绘制边缘
                DrawBorder(graphics);
                // 3、绘制区域中心
                UseTransformDraw(DrawCenter, graphics);
                // 4、绘制形状描述
                UseTransformDraw(DrawDescription, graphics);
                // 恢复颜色
                BackColor = tempBackColor;
                return;
            }
            //感兴趣根据是否选中绘制
            else if (IsInterest && IsSelected)
            {
                // 1.1、绘制（填充）背景区域
                //UseTransformDraw(DrawRegion, graphics);
                DrawRegion(graphics);
                // 1.2、绘制水平方向箭头
                UseTransformDraw(DrawVerticalDirectionArrows, graphics);
            }
            // 2、绘制边缘
            DrawBorder(graphics);
            // 3、绘制区域中心
            UseTransformDraw(DrawCenter, graphics);
            // 4、绘制形状描述
            UseTransformDraw(DrawDescription, graphics);
        }
        public override void DrawHandles(Graphics graphics)
        {
            if (!IsSelected) return;
            UseDrawHandles(graphics);
        }
        public override void Move(float deltaX, float deltaY)
        {
            _rectangleF.X += deltaX;
            _rectangleF.Y += deltaY;
            Points = GetRotatedCorners(Region);
        }
        public override void MoveHandleTo(PointF point, int handleNumber)
        {
            Points = GetRotatedCorners(Region);
            PointF[] points = null;
            float offset;
            float length1;
            float length2;
            PointF newPoint1;
            switch (handleNumber)
            {
                case 1:
                    points = GetRectangleDiagonalPoint(Points[2],  point, Angle);
                    MatrixInverse(points, Angle,1);
                    break;
                case 2:

                    //方法一：两边调整
                    //offset = (DistanceToLine(point, Points[0], Points[1]) - DistanceToLine(Points[2], Points[0], Points[1]));
                    //Height = Height + offset;
                    //Y = Y - offset / 2;
                    //方法二：
                    // 当前长度：计算当前点到底边的垂直距离
                    length1 = DistanceToLine(point, Points[3], Points[2]);
                    // 原始长度：计算左上角点底边的垂直距离
                    length2 = DistanceToLine(Points[0], Points[3], Points[2]);
                    // 计算偏移量
                    offset = (length1 - length2);
                    // 当前点延长 偏移量距离后的点
                    newPoint1 = TranslatePoint(Points[0], Angle + 90, -offset);
                    // 计算获取新的矩形角点
                    points = GetRectangleDiagonalPoint(Points[2], newPoint1, Angle);
                    // 将矩形使用矩阵逆解
                    MatrixInverse(points, Angle, 1);
                    break;
                case 3:
                    points = GetRectangleDiagonalPoint(Points[3], point, Angle);
                    MatrixInverse(points, Angle,2);
                    break;
                case 4:
                    //方法一：两边调整
                    //offset = (DistanceToLine(point, Points[3], Points[0]) - DistanceToLine(Points[1], Points[3], Points[0]));
                    //Width = Width + offset;
                    //X = X - offset / 2;
                    //方法2：
                    // 当前长度 
                    length1 = DistanceToLine(point, Points[3], Points[0]);
                    // 原始长度
                    length2 = DistanceToLine(Points[1], Points[3], Points[0]);
                    // 计算偏移
                    offset = (length1 - length2);
                    // 当前点延长指定距离
                    newPoint1 = TranslatePoint(Points[1], Angle, offset);
                    // 重新计算角点
                    points = GetRectangleDiagonalPoint(Points[3], newPoint1, Angle);
                    // 矩形矩阵逆解（）
                    MatrixInverse(points, Angle, 2);
                    break;
                case 5:
                    points = GetRectangleDiagonalPoint(Points[0], point, Angle);
                    MatrixInverse(points, Angle, 3);
                    break;
                case 6:
                    //方法一：两边调整
                    //offset = (DistanceToLine(point, Points[0], Points[1]) - DistanceToLine(Points[2], Points[0], Points[1]));
                    //Height = Height + offset;
                    //Y = Y - offset / 2;
                    //方法2：
                    length1 = DistanceToLine(point, Points[1], Points[0]);
                    // 原始长度
                    length2 = DistanceToLine(Points[2], Points[1], Points[0]);
                    // 计算偏移
                    offset = (length1 - length2);
                    // 当前点延长指定距离
                    newPoint1 = TranslatePoint(Points[2], Angle + 90, offset);
                    // 重新计算角点
                    points = GetRectangleDiagonalPoint(Points[0], newPoint1, Angle);
                    // 矩形矩阵逆解（）
                    MatrixInverse(points, Angle, 3);
                    break;
                case 7:
                    points = GetRectangleDiagonalPoint(Points[1], point, Angle);
                    MatrixInverse(points, Angle,4);
                    break;
                case 8:
                    //方法一：两边调整
                    //offset = (DistanceToLine(point, Points[2], Points[1]) - DistanceToLine(Points[0], Points[2], Points[1]));
                    //Width = Width + offset;
                    //X = X - offset / 2;
                    //方法2：
                    // 当前长度 
                    length1 = DistanceToLine(point, Points[2], Points[1]);
                    // 原始长度
                    length2 = DistanceToLine(Points[3], Points[2], Points[1]);
                    // 计算偏移
                    offset = (length1 - length2);
                    // 当前点延长指定距离
                    newPoint1 = TranslatePoint(Points[3], Angle, -offset);
                    // 重新计算角点
                    points = GetRectangleDiagonalPoint(Points[1], newPoint1, Angle);
                    // 矩形矩阵逆解（）
                    MatrixInverse(points, Angle, 4);
                    break;
            }
        }
        public override void Rotate(PointF point1, PointF point2)
        {
            // 1、计算旋转中心（矩形中心）
            PointF rotateCenter = new PointF(X + Width / 2f, Y + Height / 2f);
            // 2、计算当前鼠标位置相对于中心点的向量
            PointF currentVector = new PointF(point1.X - rotateCenter.X, point1.Y - rotateCenter.Y);
            // 3、计算上次鼠标位置相对于中心点的向量
            PointF lastVector = new PointF(point2.X - rotateCenter.X, point2.Y - rotateCenter.Y);
            // 4、计算叉积（z分量）来确定旋转方向
            float crossProduct = lastVector.X * currentVector.Y - lastVector.Y * currentVector.X;
            // 5、计算点积和向量长度来计算角度变化
            float dotProduct = lastVector.X * currentVector.X + lastVector.Y * currentVector.Y;
            float lastLength = (float)Math.Sqrt(lastVector.X * lastVector.X + lastVector.Y * lastVector.Y);
            float currentLength = (float)Math.Sqrt(currentVector.X * currentVector.X + currentVector.Y * currentVector.Y);
            // 6、数值判断计算
            // 避免除以零
            if (lastLength > 0 && currentLength > 0)
            {
                float cosAngle = dotProduct / (lastLength * currentLength);
                // 确保cosAngle在有效范围内[-1,1]，避免浮点误差
                cosAngle = Math.Max(-1, Math.Min(1, cosAngle));
                float angleDelta = (float)(Math.Acos(cosAngle) * (180.0 / Math.PI));
                // 根据叉积符号确定旋转方向
                // 逆时针旋转
                if (crossProduct > 0) Angle += angleDelta;
                // 顺时针旋转
                else if (crossProduct < 0) Angle -= angleDelta;
                // 限制角度在0-360度之间
                Angle = Angle % 360;
                if (Angle < 0) Angle += 360;
            }
            Points = GetRotatedCorners(Region);
        }
        public override PointF GetHandle(int handleNumber)
        {
            //旋转前的矩形
            RectangleF rectangle = Region;
            //获取旋转后的角点：左上、右上、右下、左下
            PointF[] points = GetRotatedCorners(rectangle);
            //获取角点对应的中点：左中、上中、右中、下中
            PointF[] pointCenters = GetMidPoints(Region);
            float x, y;
            x = rectangle.X;
            y = rectangle.Y;
            switch (handleNumber)
            {
                case 1:
                    x = points[0].X;
                    y = points[0].Y;
                    break;
                case 2:
                    x = pointCenters[1].X;
                    y = pointCenters[1].Y;
                    break;
                case 3:
                    x = points[1].X;
                    y = points[1].Y;
                    break;
                case 4:
                    x = pointCenters[2].X;
                    y = pointCenters[2].Y;
                    break;
                case 5:
                    x = points[2].X;
                    y = points[2].Y;
                    break;
                case 6:
                    x = pointCenters[3].X;
                    y = pointCenters[3].Y;
                    break;
                case 7:
                    x = points[3].X;
                    y = points[3].Y;
                    break;
                case 8:
                    x = pointCenters[0].X;
                    y = pointCenters[0].Y;
                    break;
                case 9:
                    x = points[1].X;
                    y = points[1].Y;
                    break;
            }
            return new PointF(x, y);
        }
        public override int HitTest(PointF point)
        {
            if (IsSelected)
            {
                for (int i = 1; i <= HandleCount; i++)
                {
                    if (i == 9)
                        if (GetRotateHandle().Contains(point)) return i;
                    if (GetHandleRectangle(i).Contains(point)) return i;
                }
            }
            if (PointInObject(point)) return 0;
            return -1;
        }
        public override bool IntersectsWith(RectangleF rectangle)
        {
            return Region.IntersectsWith(rectangle);
        }
        public override Cursor GetHandleCursor(int handleNumber)
        {
            switch (handleNumber)
            {
                case 1:
                case 5:
                    // 默认是 SizeNWSE（左上↖右下↘）4
                    if (Angle >= 25 && Angle < 70) return Cursors.SizeNS;
                    if (Angle >= 70 && Angle < 115) return Cursors.SizeNESW;
                    if (Angle >= 115 && Angle < 160) return Cursors.SizeWE;
                    if (Angle >= 160 && Angle < 205) return Cursors.SizeNWSE;
                    if (Angle >= 205 && Angle < 250) return Cursors.SizeNS;
                    if (Angle >= 250 && Angle < 295) return Cursors.SizeNS;
                    if (Angle >= 295 && Angle < 340) return Cursors.SizeWE;
                    if (Angle >= 340 && Angle < 25) return Cursors.SizeNESW;
                    return Cursors.SizeNWSE;
                case 2:
                case 6:
                    if (Angle >= 25 && Angle < 70) return Cursors.SizeNESW;
                    if (Angle >= 70 && Angle < 115) return Cursors.SizeWE;
                    if (Angle >= 115 && Angle < 160) return Cursors.SizeNWSE;
                    if (Angle >= 160 && Angle < 205) return Cursors.SizeNS;
                    if (Angle >= 205 && Angle < 250) return Cursors.SizeNESW;
                    if (Angle >= 250 && Angle < 295) return Cursors.SizeWE;
                    if (Angle >= 295 && Angle < 340) return Cursors.SizeNWSE;
                    if (Angle >= 340 && Angle < 25) return Cursors.SizeNESW;
                    return Cursors.SizeNS;
                case 3:
                case 7:
                    if (Angle >= 25 && Angle < 70) return Cursors.SizeWE;
                    if (Angle >= 70 && Angle < 115) return Cursors.SizeNWSE;
                    if (Angle >= 115 && Angle < 160) return Cursors.SizeNS;
                    if (Angle >= 160 && Angle < 205) return Cursors.SizeNESW;
                    if (Angle >= 205 && Angle < 250) return Cursors.SizeWE;
                    if (Angle >= 250 && Angle < 295) return Cursors.SizeNWSE;
                    if (Angle >= 295 && Angle < 340) return Cursors.SizeNS;
                    if (Angle >= 340 && Angle < 25) return Cursors.SizeNESW;
                    return Cursors.SizeNESW;
                case 4:
                case 8:
                    if (Angle >= 25 && Angle < 70) return Cursors.SizeNWSE;
                    if (Angle >= 70 && Angle < 115) return Cursors.SizeNS;
                    if (Angle >= 115 && Angle < 160) return Cursors.SizeNESW;
                    if (Angle >= 160 && Angle < 205) return Cursors.SizeWE;
                    if (Angle >= 205 && Angle < 250) return Cursors.SizeNWSE;
                    if (Angle >= 250 && Angle < 295) return Cursors.SizeNS;
                    if (Angle >= 295 && Angle < 340) return Cursors.SizeNESW;
                    if (Angle >= 340 && Angle < 25) return Cursors.SizeNESW;
                    return Cursors.SizeWE;
                case 9:
                    return RotateCursor;
                default:
                    return Cursors.Default;
            }
        }
        protected override bool PointInObject(PointF point)
        {
            // 是否在旋转手柄
            RectangleF rect = new RectangleF(this.Region.Right - 10, this.Region.Top - 16,rotateHandleSize, rotateHandleSize);
            if (rect.Contains(point)) return true;
            // 是否在旋转的矩形内
            return IsInRotatedRectangle(point);
        }
        #endregion

        #region 辅助方法
        protected void UseTransformDraw(Action<Graphics> method, Graphics graphics)
        {
            RectangleF rectangle = Region;
            // 1、保存原始变换状态
            GraphicsState state = graphics.Save();
            // 2、设置旋转中心（矩形中心）
            PointF center = new PointF(rectangle.X + rectangle.Width / 2f, rectangle.Y + rectangle.Height / 2f);
            // 3、应用旋转变换
            graphics.TranslateTransform(center.X, center.Y);
            graphics.RotateTransform(Angle);
            graphics.TranslateTransform(-center.X, -center.Y);
            // 4、**执行方法**
            method.Invoke(graphics);
            // 5、恢复原始变换状态
            graphics.Restore(state);
        }
        protected void DrawDescription(Graphics graphics)
        {
            using (SolidBrush brush = new SolidBrush(Color.LightGreen))
            {
                Font descriptionFont = new Font("Arial", 9);
                string text = $"{Description}(X:{X},Y:{Y}),A:{Angle}";
                SizeF maxTextSize = graphics.MeasureString(text, descriptionFont);
                float x = X + (Width - maxTextSize.Width) / 2;
                float y = Y + (Height - maxTextSize.Height) / 2 - maxTextSize.Height;
                graphics.DrawString(text, descriptionFont, brush, x, y);
            }
        }
        private void DrawBorder(Graphics graphics)
        {
            using (GraphicsPath path = new GraphicsPath())
            {
                using (Pen pen = new Pen(Color.FromArgb(200, BackColor),1))
                {
                    graphics.DrawPolygon(pen, GetRotatedCorners(Region));
                }
            }
        }
        private void DrawRegion(Graphics graphics)
        {
            using (GraphicsPath path = new GraphicsPath())
            {
                path.AddPolygon(GetRotatedCorners(Region));
                Region region = new Region(path);
                using (SolidBrush brush = new SolidBrush(Color.FromArgb(Alpha, BackColor)))
                {
                    graphics.FillRegion(brush, region);
                }
            }
        }
        public void UseDrawHandles(Graphics graphics)
        {
            UseTransformDraw(DrawRotateHandle, graphics);
            using (SolidBrush brush = new SolidBrush(Color.FromArgb(200, HandleColor)))
            {
                for (int i = 1; i < HandleCount; i++)
                {
                    graphics.FillEllipse(brush, GetHandleRectangle(i));
                }
            }
        }
        private void DrawRotateHandle(Graphics graphics)
        {
            using (Pen arcPen = new Pen(HandleColor, 1))
            {
                graphics.DrawArc(arcPen, this.Region.Right - 3, this.Region.Top - 9,
                    rotateHandleSize, rotateHandleSize, 245, 135);
            }
        }
        /// <summary> 在左右边框中间位置绘制垂直方向箭头（↓↓）  </summary>
        private void DrawVerticalDirectionArrows(Graphics graphics)
        {
            RectangleF rectangle = Region;
            // 1、计算左右边框的中间X坐标
            float leftMidX = rectangle.Left;
            float rightMidX = rectangle.Right;
            float verticalCenterY = rectangle.Top + rectangle.Height / 2;
            // 2、箭头大小（根据矩形大小自适应）
            float arrowSize = Math.Min(10, rectangle.Height / 4);
            float arrowHalfSize = arrowSize / 2;
            // 3、绘制箭头
            using (Pen arrowPen = new Pen(BackColor, BorderWidth + 1))
            {
                // 3.1 左侧向下箭头（垂直方向）
                PointF leftArrowCenter = new PointF(leftMidX, verticalCenterY + arrowSize);
                PointF leftArrowRight = new PointF(leftMidX + arrowHalfSize, verticalCenterY + arrowSize / 2);
                PointF leftArrowLeft = new PointF(leftMidX - arrowHalfSize, verticalCenterY + arrowHalfSize);
                graphics.DrawLine(arrowPen, leftArrowRight, leftArrowCenter);
                graphics.DrawLine(arrowPen, leftArrowLeft, leftArrowCenter);
                // 3.2 右侧向下箭头（垂直方向）
                PointF rightArrowCenter = new PointF(rightMidX, verticalCenterY + arrowSize);
                PointF rightArrowLeft = new PointF(rightMidX - arrowHalfSize, verticalCenterY + arrowHalfSize);
                PointF rightArrowRight = new PointF(rightMidX + arrowHalfSize, verticalCenterY + arrowHalfSize);
                graphics.DrawLine(arrowPen, rightArrowLeft, rightArrowCenter);
                graphics.DrawLine(arrowPen, rightArrowRight, rightArrowCenter);
            }
        }
        /// <summary> 获取旋转手柄 </summary>
        public RectangleF GetRotateHandle()
        {
            PointF point = GetHandle(9);
            return new RectangleF(point.X + 5, point.Y - 16, rotateHandleSize, rotateHandleSize);
        }
        /// <summary> 判断点是否在矩形内（即使矩形旋转了角度） </summary>
        private bool IsInRotatedRectangle(PointF point)
        {
            RectangleF rect = this.Region;
            PointF center = new PointF(rect.X + rect.Width / 2f, rect.Y + rect.Height / 2f);
            // 将检测点反向旋转
            GetTrigonometric(-Angle, out float cos, out float sin);
            float dx = point.X - center.X;
            float dy = point.Y - center.Y;
            //获取旋转点 
            PointF unrotatedPoint = new PointF(dx * cos - dy * sin + center.X, dx * sin + dy * cos + center.Y);
            return rect.Contains((int)unrotatedPoint.X, (int)unrotatedPoint.Y);
        }
        #region 旋转辅助方法
        /// <summary> 获取矩形角点数组： </summary>
        /// <param name="fiexedPoint">固定点</param>
        /// <param name="point">移动的点</param>
        /// <param name="angle">角度</param>
        /// <returns>矩形四个角角点</returns>
        public PointF[] GetRectangleDiagonalPoint(PointF fiexedPoint, PointF point, float angle)
        {
            // 1. 计算矩形的中心点
            PointF center = new PointF((point.X + fiexedPoint.X) / 2, (point.Y + fiexedPoint.Y) / 2);
            // 2. 计算弧度、cos、sin
            GetTrigonometric( angle, out float cos, out float sin);
            // 3. 计算新的宽度和高度（基于新的左上角和固定的右下角）
            float dx = fiexedPoint.X - point.X;
            float dy = fiexedPoint.Y - point.Y;
            float width = dx * cos + dy * sin;
            float height = -dx * sin + dy * cos;
            // 4. 计算未旋转时的局部角点（基于新的宽度和高度）
            float halfW = width / 2;
            float halfH = height / 2;
            PointF[] localPoint = new PointF[4];
            localPoint[0] = new PointF(-halfW, -halfH);   // 左上 
            localPoint[1] = new PointF( halfW, -halfH);   // 左下
            localPoint[2] = new PointF( halfW,  halfH);   // 右下
            localPoint[3] = new PointF(-halfW,  halfH);   // 右上
            // 5. 旋转角点到全局坐标
            PointF[] cornerPoint = new PointF[4];
            for (int i = 0; i < 4; i++)
            {
                cornerPoint[i] = new PointF(
                    localPoint[i].X * cos - localPoint[i].Y * sin + center.X,
                    localPoint[i].X * sin + localPoint[i].Y * cos + center.Y
                );
            }
            return cornerPoint;
        }
        /// <summary> 角点逆转：将角点根据角度逆转（如果有角度旋转） </summary>
        public PointF[] MatrixInverse(PointF[] cornerPoints, float angle,int cornerIndex = 1)
        {
            // 1. 计算中心点
            float centerX = (cornerPoints[0].X + cornerPoints[2].X) / 2f;
            float centerY = (cornerPoints[0].Y + cornerPoints[2].Y) / 2f;
            // 2. 创建逆向旋转矩阵（-θ）
            Matrix matrix = new Matrix();
            matrix.RotateAt(-angle, new PointF(centerX, centerY));
            // 3. 逆向旋转角点 // 直接修改原数组
            matrix.TransformPoints(cornerPoints);
            float minX = float.MaxValue, maxX = float.MinValue;
            float minY = float.MaxValue, maxY = float.MinValue;
            // 4.计算宽高
            foreach (PointF p in cornerPoints)
            {
                minX = Math.Min(minX, p.X);
                maxX = Math.Max(maxX, p.X);
                minY = Math.Min(minY, p.Y);
                maxY = Math.Max(maxY, p.Y);
            }
            float width = maxX - minX;
            float height = maxY - minY;
            Region = new RectangleF(cornerPoints[cornerIndex - 1], new SizeF(width, height));
            return cornerPoints;
        }
        /// <summary> 获取矩形角点：左上、右上、右下、左下 </summary>
        public PointF[] GetRotatedCorners(RectangleF rect)
        {
            PointF center = new PointF(rect.X + rect.Width / 2, rect.Y + rect.Height / 2);
            float width = rect.Width;
            float height = rect.Height;
            // 四个角点相对于中心的初始位置（未旋转）
            PointF[] corners = new PointF[4];
            corners[0] = new PointF(-width / 2, -height / 2);  // 左上
            corners[1] = new PointF(width / 2, -height / 2);  // 右上
            corners[2] = new PointF(width / 2, height / 2);  // 右下
            corners[3] = new PointF(-width / 2, height / 2);  // 左下
            GetTrigonometric(Angle, out float cos, out float sin);
            // 旋转每个角点并加上中心坐标
            for (int i = 0; i < 4; i++)
            {
                // 应用旋转矩阵
                float x = corners[i].X * cos - corners[i].Y * sin;
                float y = corners[i].X * sin + corners[i].Y * cos;
                // 平移回中心位置
                corners[i] = new PointF(x + center.X, y + center.Y);
            }
            return corners;
        }
        /// <summary> 获取中点：获取两个角点的中间点  </summary>
        public PointF GetMidPoint(PointF p1, PointF p2)
        {
            return new PointF((p1.X + p2.X) / 2, (p1.Y + p2.Y) / 2);
        }
        /// <summary> 获取矩形中间点：左中、上中、右中、下中 </summary>
        public PointF[] GetMidPoints(RectangleF rect)
        {
            //获取旋转后的角点
            PointF[] points = GetRotatedCorners(rect);
            //获取角点对应的中点：左中、上中、右中、下中
            PointF[] pointCenters = GetRotatedCorners(rect);
            pointCenters[0] = GetMidPoint(points[0], points[3]);
            pointCenters[1] = GetMidPoint(points[0], points[1]);
            pointCenters[2] = GetMidPoint(points[1], points[2]);
            pointCenters[3] = GetMidPoint(points[2], points[3]);
            return pointCenters;
        }
        /// <summary> 计算点到线段的垂直距离  </summary>
        public float DistanceToLine(PointF point, PointF lineStart, PointF lineEnd)
        {
            // 线段长度平方
            float lineLengthSquared = (float)(Math.Pow(lineEnd.X - lineStart.X, 2) + Math.Pow(lineEnd.Y - lineStart.Y, 2));
            // 如果线段长度为0，退化为点到点的距离
            if (lineLengthSquared == 0)
                return (float)Math.Sqrt(Math.Pow(point.X - lineStart.X, 2) + Math.Pow(point.Y - lineStart.Y, 2));
            // 计算投影比例
            float t = ((point.X - lineStart.X) * (lineEnd.X - lineStart.X) + 
                       (point.Y - lineStart.Y) * (lineEnd.Y - lineStart.Y)) / lineLengthSquared;
            // 限制t在[0,1]范围内，确保投影点在线段上
            t = Math.Max(0, Math.Min(1, t));
            // 计算投影点坐标
            PointF projection = new PointF( lineStart.X + t * (lineEnd.X - lineStart.X), lineStart.Y + t * (lineEnd.Y - lineStart.Y));
            // 返回点到投影点的距离
            return (float)Math.Sqrt(Math.Pow(point.X - projection.X, 2) + Math.Pow(point.Y - projection.Y, 2));
        }
        /// <summary> 获取输入角度的正弦余弦值 </summary>
        public void GetTrigonometric(float angle,out float cos ,out float sin)
        {
            float angleRad = (float)(angle * Math.PI / 180);
            cos = (float)Math.Cos(angleRad);
            sin = (float)Math.Sin(angleRad);
        }
        /// <summary> 将输入点沿指定角度平移指定长度 </summary>
        public PointF TranslatePoint(PointF originalPoint, float angle, float length)
        {
            // 获取正玄余玄值
            GetTrigonometric(angle, out float cos, out float sin);
            // 计算x和y方向的变化量
            float deltaX = (length * cos);
            float deltaY = (length * sin);
            // 创建并返回新点
            return new PointF(originalPoint.X + deltaX, originalPoint.Y + deltaY);
        }
        #endregion
        #endregion
    }
}
